package com.kinsin.kinsinutil

import org.junit.Test
import kotlin.math.pow
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith

class StorageUnitUtilsTest {

    // region 正向转换测试
    @Test
    fun testBytesToKB() {
        assertEquals(1.0, StorageUnitUtils.bytesToKB(1024))
        assertEquals(1.5, StorageUnitUtils.bytesToKB(1536))
    }

    @Test
    fun testBytesToMB() {
        assertEquals(1.0, StorageUnitUtils.bytesToMB(1024.0.pow(2).toLong()))
        assertEquals(2.5, StorageUnitUtils.bytesToMB((2.5 * 1024 * 1024).toLong()))
    }

    @Test
    fun testBytesToGB() {
        assertEquals(1.0, StorageUnitUtils.bytesToGB(1024.0.pow(3).toLong()))
        assertEquals(3.0, StorageUnitUtils.bytesToGB(3L * 1024 * 1024 * 1024))
    }

    @Test
    fun testBytesToTB() {
        assertEquals(1.0, StorageUnitUtils.bytesToTB(1024.0.pow(4).toLong()))
    }

    @Test
    fun testBytesToPB() {
        assertEquals(1.0, StorageUnitUtils.bytesToPB(1024.0.pow(5).toLong()))
    }
    // endregion

    // region 新增EB相关测试
    @Test
    fun testBytesToEB() {
        assertEquals(1.0, StorageUnitUtils.bytesToEB(1024.0.pow(6).toLong()))
    }

    @Test
    fun testEbToBytes() {
        assertEquals(1024.0.pow(6).toLong(), StorageUnitUtils.ebToBytes(1.0))
    }

    @Test
    fun testBytesToHumanReadable_EB() {
        // EB边界测试
        val ebValue = 1024.0.pow(6).toLong()
        assertEquals("1.00 EB", StorageUnitUtils.bytesToHumanReadable(ebValue))

        // 超过PB但小于EB的情况
        val midValue = (1024.0.pow(5) * 1.5).toLong() // 1.5PB
        assertEquals("1.50 PB", StorageUnitUtils.bytesToHumanReadable(midValue))
    }

    @Test
    fun testEbToBytes_Overflow() {
        val exception = assertFailsWith<ArithmeticException> {
            StorageUnitUtils.ebToBytes(Double.MAX_VALUE)
        }
        assertEquals("Value ${Double.MAX_VALUE} exceeds Long.MAX_VALUE", exception.message)
    }
    // endregion

    // region bytesToHumanReadable 测试
    @Test
    fun testBytesToHumanReadable_BoundaryValues() {
        assertEquals("1023 B", StorageUnitUtils.bytesToHumanReadable(1023))
        assertEquals("1.00 KB", StorageUnitUtils.bytesToHumanReadable(1024))
        assertEquals("1.00 MB", StorageUnitUtils.bytesToHumanReadable(1024 * 1024))
        assertEquals("1.00 GB", StorageUnitUtils.bytesToHumanReadable(1024 * 1024 * 1024))
        assertEquals("1.00 TB", StorageUnitUtils.bytesToHumanReadable(1024.0.pow(4).toLong()))
        assertEquals("1.00 PB", StorageUnitUtils.bytesToHumanReadable(1024.0.pow(5).toLong()))
    }

    @Test
    fun testBytesToHumanReadable_WithDecimalPrecision() {
        assertEquals("1.50 KB", StorageUnitUtils.bytesToHumanReadable(1536))
        assertEquals("2.50 MB", StorageUnitUtils.bytesToHumanReadable((2.5 * 1024 * 1024).toLong()))
        assertEquals("3.14 GB", StorageUnitUtils.bytesToHumanReadable((3.14 * 1024 * 1024 * 1024).toLong()))
    }

    @Test
    fun testBytesToHumanReadable_LocalizationSafety() {
        // 确保任何语言环境都显示小数点
        assertEquals("1.23 KB", StorageUnitUtils.bytesToHumanReadable(1260))
    }

    @Test
    fun testBytesToHumanReadable_ZeroValue() {
        assertEquals("0 B", StorageUnitUtils.bytesToHumanReadable(0))
    }

    @Test
    fun testBytesToHumanReadable_NegativeInput() {
        val exception = assertFailsWith<IllegalArgumentException> {
            StorageUnitUtils.bytesToHumanReadable(-1)
        }
        assertEquals("Byte size cannot be negative", exception.message)
    }
    // endregion

    // region 反向转换测试
    @Test
    fun testKbToBytes() {
        assertEquals(1024L, StorageUnitUtils.kbToBytes(1.0))
        assertEquals(1536L, StorageUnitUtils.kbToBytes(1.5))
    }

    @Test
    fun testMbToBytes() {
        assertEquals(1024 * 1024L, StorageUnitUtils.mbToBytes(1.0))
        assertEquals((2.5 * 1024 * 1024).toLong(), StorageUnitUtils.mbToBytes(2.5))
    }

    @Test
    fun testGbToBytes() {
        assertEquals(1024.0.pow(3).toLong(), StorageUnitUtils.gbToBytes(1.0))
    }

    @Test
    fun testTbToBytes() {
        assertEquals(1024.0.pow(4).toLong(), StorageUnitUtils.tbToBytes(1.0))
    }

    @Test
    fun testPbToBytes() {
        assertEquals(1024.0.pow(5).toLong(), StorageUnitUtils.pbToBytes(1.0))
    }

    @Test
    fun testReverseConversion_Rounding() {
        assertEquals(1025L, StorageUnitUtils.kbToBytes(1.0009765625)) // 1KB + 1字节
    }

    @Test
    fun testReverseConversion_OverflowProtection() {
        val exception = assertFailsWith<ArithmeticException> {
            StorageUnitUtils.pbToBytes(Double.MAX_VALUE)
        }
        assertEquals("Value ${Double.MAX_VALUE} exceeds Long.MAX_VALUE", exception.message)
    }

    @Test
    fun testReverseConversion_InvalidInput() {
        val exception = assertFailsWith<IllegalArgumentException> {
            StorageUnitUtils.kbToBytes(Double.NaN)
        }
        assertEquals("Invalid numerical value", exception.message)
    }
    // endregion

    // region 综合测试
    @Test
    fun testConversionRoundTrip() {
        val originalBytes = 3.14 * 1024 * 1024 // 3.14MB
        val bytes = StorageUnitUtils.mbToBytes(3.14)
        assertEquals("3.14 MB", StorageUnitUtils.bytesToHumanReadable(bytes))
    }

    @Test
    fun testMaxLongValue() {
        val maxValue = Long.MAX_VALUE
        assertEquals("8.00 EB", StorageUnitUtils.bytesToHumanReadable(maxValue)) // 注意：可能需要扩展EB支持
    }
    // endregion
}